﻿using Core.DataAccess.Model.Project.Queue;
using Core.Framework.Model.ViewModel;
using Core.Framework.Model.WebSockets;
using Core.WebSocketApi.Model;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using System.Net.WebSockets;

namespace Core.WebSocketApi.Controllers.Socket
{
    [Route(".v1/socket/[controller]")]
    [ApiController]
    public class UserController : BaseApiController
    {
        [HttpGet("{token}/{projectToken}")]
        public IResult Get(string token, string projectToken)
        {
            var result = this.iSocketUser.GetUserInfoByToken(token, projectToken);

            return new ApiResult
            {
                code = result.Item1 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item2
            };
        }

        [HttpGet("{userID}/{projectToken}")]
        public IResult Get(int userid, string projectToken)
        {
            var result = this.iSocketUser.LoginByKey(userid, projectToken, 24 * 3);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpGet("{userID}/{projectToken}.{hour}h")]
        public IResult Get(int userid, string projectToken, int hour)
        {
            var result = this.iSocketUser.LoginByKey(userid, projectToken, hour);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpPost]
        public IResult Reg(ProjectModuleUser model)
        {
            var result = this.iSocketUser.Reg(model);
            return new ApiResult
            {
                code = result.Item1 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item2,
                info = result.Item3
            };
        }

        [HttpPost(".user")]
        public IResult Login(ScoketUserRequest request)
        {
            var result = this.iSocketUser.Login(request.user, request.password, request.projectToken, request.hour);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpPost(".phone")]
        public IResult LoginByPhone(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginByPhone(request.phone, request.password, request.projectToken, request.hour);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpPost(".client")]
        public IResult LoginByClient(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginByClient(request.uuid, request.projectToken, request.hour);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpPost(".wchat")]
        public IResult LoginByWChat(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginByWChat(request.wchat, request.projectToken, request.hour);

            return new ApiResult
            {
                code = result.Item2 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1
            };
        }

        [HttpPost(".wsbyclient")]
        public IResult LoginWebSocketByClient(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginWebSocketByClient(request.uuid, request.projectToken, request.parameter.Replace("\"","'"), request.url);

            return new ApiResult
            {
                code = result.Item3 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1,
                info = result.Item2
            };
        }

        [HttpPost(".wsbytoken")]
        public IResult LoginWebSocketByUserToken(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginWebSocketByUserToken(request.token, request.projectToken, request.parameter, request.url);

            return new ApiResult
            {
                code = result.Item3 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1,
                info = result.Item2
            };
        }

        [HttpPost(".wsbywchat")]
        public IResult LoginWebSocketByWChat(ScoketUserRequest request)
        {
            var result = this.iSocketUser.LoginWebSocketByWChat(request.wchat, request.projectToken, request.parameter, request.url);

            return new ApiResult
            {
                code = result.Item3 ? CodeResult.SUCCESS : CodeResult.DATA_NOT_FOUND,
                date = result.Item1,
                info = result.Item2
            };
        }

        [HttpPut]
        public IResult UpdateUserInfo(ProjectModuleUser model)
        {
            var result = this.iSocketUser.UpdateUserInfo(model);

            return new ApiResult
            {
                code = model == null ? CodeResult.PARAMS_TYPE_ERROR : CodeResult.SUCCESS,
                date = result
            };
        }

        [HttpPut(".paras")]
        public IResult UpdateUserInfoParas(ProjectModuleUser model)
        {
            var result = this.iSocketUser.UpdateUserInfoParas(model.Id,model.Token,model.ProjectToken,model.Paras);

            return new ApiResult
            {
                code = model == null ? CodeResult.PARAMS_TYPE_ERROR : CodeResult.SUCCESS,
                date = result
            };
        }

        [HttpDelete("{token}/{projectToken}")]
        public void OutLogin(string token,string projectToken)
        {
            this.iSocketUser.OutLogin(token, projectToken);
            {
                //WebSocketApplication.ClientsPool
                // 处理 客户机下线
            }
        }

        [HttpDelete(".wsbyservice{token}")]
        public IResult OutLoginByServiceToken(string token)
        {
            var clients = WebSocketApplication.ClientsPool
                    .Where(a => a.Key.State == WebSocketState.Open && a.Value.ServiceToken == token);

            // 判断是否在线
            if (clients.Count() > 0)
            {
                // 下线
                foreach (var item in clients)
                {
                    WebSocketApplication.ClientsPool.TryRemove(item.Key, out ClientInfo model);
                    WebSocketApplication.SendAsync(item.Key, new { type = "userOutlogin", date = "以下线" });
                    item.Key.Dispose();
                }
            }

            return new ApiResult
            {
                code = CodeResult.SUCCESS
            };
        }

        [HttpDelete(".ws{token}")]
        public IResult OutLogin(string token)
        {
            var clients = WebSocketApplication.ClientsPool
                    .Where(a => a.Key.State == WebSocketState.Open && a.Value.ClientToken == token);

            // 判断是否在线
            if (clients.Count() > 0)
            {
                // 下线
                foreach (var item in clients)
                {
                    try
                    {
                        WebSocketApplication.ClientsPool.TryRemove(item.Key, out ClientInfo model);
                        WebSocketApplication.SendAsync(item.Key, new { type = "userOutlogin", date = "以下线" });
                        item.Key.Dispose();
                    }
                    catch 
                    {
                    }
                }
            }


            return new ApiResult
            {
                code =  CodeResult.SUCCESS
            };

        }

    }
}
